
cmake_minimum_required(VERSION 3.10)

# 项目名称
project(cx_demo)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)

set(SRC_DIR ${CMAKE_CURRENT_LIST_DIR})

set(VERSION_MAJOR_1   13)
set(VERSION_MINPR_1   14)

# 添加 lib 子目录
# 上面这行不能屏蔽掉，如果屏蔽掉，在VS里不会有cx_lib这一工程，也就不会生成cx_lib.lib，而下面的  target_link_libraries(cx_demo cx_lib) 会
# 让 cx_demo 对 cx_lib 进行依赖，从而出现 “cx_lib不存在的报错”
add_subdirectory(cx_lib)

# cx_lib2 文件夹要存在，要不然报错，同时里面也有个 CMakeLists.txt 文件，可以是空的
# add_subdirectory(cx_lib2)


# 将文件组织成文件夹放在一起
set(EFFECT_FILES 
  "modules/Effects/static.cpp"
  "modules/Effects/static.h"
  "modules/Effects/wave.cpp"
  "modules/Effects/wave.h"
)
set(
  COMMON_FILES
  "common.cpp" 
  "modules/log.cpp"
)
source_group("Effects" FILES ${EFFECT_FILES})
source_group("Common" FILES ${COMMON_FILES})

# 会对 config.h.in 里的内容进行替换并生成 version.h，但这个文件在cmake生成的文件夹里
configure_file(config.h.in  my_version.h)

# 平台分支
if (APPLE)
  set(FILE_FILES "modules/Files/mac_read.hpp")
elseif(WIN32)
  set(FILE_FILES "modules/Files/win_read.hpp")
elseif(UNIX)
  set(FILE_FILES "modules/Files/linux_read.hpp")
else()
  message(FATAL_ERROR "Unsupported platform")
endif()

# 添加源文件
add_executable(
  cx_demo 
  "main.cpp" 
  ${EFFECT_FILES}
  ${COMMON_FILES}
)

# 后续添加源文件
target_sources(cx_demo PRIVATE ${FILE_FILES})

# 链接静态库到可执行文件
target_link_libraries(cx_demo cx_lib)

# 添加头文件路径
# 下面添加 ${PROJECT_BINARY_DIR} 是因为 configure_file 生成的 my_version.h在构建目录下
# ${CMAKE_CURRENT_BINARY_DIR}： 当前 CMakeLists.txt 所在目录对应的构建目录
# ${PROJECT_BINARY_DIR}：顶层 CMakeLists.txt 的构建目录（一般是你运行 cmake .. 的那个 build/ 目录）
target_include_directories(
  cx_demo
  PRIVATE
  ${SRC_DIR}/modules
  ${SRC_DIR}/modules/Effects
  ${SRC_DIR}/modules/Files
  ${PROJECT_BINARY_DIR}
)


# 因为 cx_lib2 的 CMakeLists.txt 是空的，所有没有lib生成，但在VS 侧会添加依赖，因此会报错，该lib并不存在
# target_link_libraries(cx_demo cx_lib2)

# learn how to use if to check variable
# STATUS	输出普通信息，默认显示，带 -- 前缀，适合打印编译状态
# WARNING	输出 警告信息，不会终止构建
# AUTHOR_WARNING	只有启用了 CMAKE_WARN_DEPRECATED 或 CMAKE_WARN_AUTHOR_WARNING 时才显示
# SEND_ERROR	显示错误信息，但继续配置过程（不会生成构建文件）
# FATAL_ERROR	显示错误信息并 终止 CMake 配置过程
# DEPRECATION	标记已弃用信息（通常用于模块或命令）
set(IS_DEFINED "Show me around")
if (IS_DEFINED)
  message(STATUS ${IS_DEFINED})
else()
  message(STATUS "IS_DEFINED is not defined")
endif()

# learn foreach
set(TEST_FOR_EACH foo.cpp bar.cpp apple.cpp)
foreach(file ${TEST_FOR_EACH})
  message(STATUS "Get file: ${file}")
endforeach()


# option 用来定义布尔类型的缓存变量
option(ENABLE_LOG "switch of logss" ON)
if (ENABLE_LOG)
  message(STATUS "We are going to use logs")
endif()

# 注意：值是 -D* 格式，在工程的 Preprocessor Definitions 里会有 ENABLE_RUNNING; 这一项宏定义
# 现在更推荐使用 target_compile_definitions，更可控
add_definitions(-DENABLE_RUNNING)
target_compile_definitions(cx_demo PRIVATE ENABLE_FLYING TEST_VERSION=2)

# 
set(TEST_LISTS a b c d a b d e f g a)

# 输出是 a;b;c;d;a;b;d;e;f;g;a，CMake 的列表就是以 分号 ; 分隔的字符串，本质是字符串
message(STATUS "TEST_LISTS is ${TEST_LISTS}")
# 获取长度
list(LENGTH TEST_LISTS len)
message(STATUS "length of TEST_LISTS is ${len}")
# 后面追加元素，输出是 a;b;c;d;a;b;d;e;f;g;a;apple;banana
list(APPEND TEST_LISTS apple banana)
message(STATUS "TEST_LISTS is ${TEST_LISTS}")
# 前面追加元素，输出是 water;a;b;c;d;a;b;d;e;f;g;a;apple;banana
list(PREPEND TEST_LISTS water)
message(STATUS "TEST_LISTS is ${TEST_LISTS}")
# 按索引删除, 输出 a;c;d;a;b;d;e;f;g;a;apple;banana
list(REMOVE_AT TEST_LISTS 0 2)
message(STATUS "TEST_LISTS is ${TEST_LISTS}")
# 插入到指定位置，输出a;duck;c;d;a;b;d;e;f;g;a;apple;banana
list(INSERT TEST_LISTS 1 duck)
message(STATUS "TEST_LISTS is ${TEST_LISTS}")
# 按值删除 删除所有 a，结果：duck;c;d;b;d;e;f;g;apple;banana
list(REMOVE_ITEM TEST_LISTS a)
message(STATUS "TEST_LISTS is ${TEST_LISTS}")
# 去重 duck;c;d;b;e;f;g;apple;banana, 两个 d 保留了一个d
list(REMOVE_DUPLICATES TEST_LISTS)
message(STATUS "TEST_LISTS is ${TEST_LISTS}")